﻿/**
 * canvas-effect.js
 * @author Noriko Iwai
 */

// モザイク効果
// @canvas_name canvas要素のid
// @block_size  モザイクの精度（1ブロックのサイズ）
function mosaic(canvas_name, block_size)
{
	// canvas取得
	var canvas = document.getElementById(canvas_name);
	// canvasのコンテキスト取得
	var context = canvas.getContext("2d");
    // ピクセルデータ取得
    var pxdata = context.getImageData(0, 0, canvas.width, canvas.height);

    for (var i = 0; i < pxdata.height; i += block_size) {
        for (var j = 0; j < pxdata.width; j += block_size) {
            // RGB各要素
            var sum_r = 0, sum_g = 0; sum_b = 0;

            // ブロック範囲のピクセル数
            // 画像サイズの端を超える場合は画像サイズに合わせる
            var block_i = i + block_size > pxdata.height ? pxdata.height - i : block_size;
            var block_j = j + block_size > pxdata.width ? pxdata.width - j : block_size;

            // 各ブロック当たりの色要素の合計を計算
            for (var i2 = 0; i2 < block_i; i2 ++) {
                // カレント行の開始位置
                var line_i = (i + i2) * pxdata.width * 4;
                for (var j2 = 0; j2 < block_j; j2 ++) {
                    // カレントポイント
                    var data_j = line_i + ((j + j2) * 4);
                    sum_r += pxdata.data[data_j];
                    sum_g += pxdata.data[data_j + 1];
                    sum_b += pxdata.data[data_j + 2];
                }
            }
            
            // 各色要素の平均値を計算
            var block_pixel = block_i * block_j;
            sum_r /= block_pixel;
            sum_g /= block_pixel;
            sum_b /= block_pixel;
            
            // 各ブロックを平均値で塗りつぶす
            for (var i2 = 0; i2 < block_i; i2 ++) {
                // カレント行の開始位置
                var line_i = (i + i2) * pxdata.width * 4;
                for (var j2 = 0; j2 < block_j; j2 ++) {
                    // カレントポイント
                    var data_j = line_i + ((j + j2) * 4);
                    pxdata.data[data_j] = sum_r;
                    pxdata.data[data_j + 1] = sum_g;
                    pxdata.data[data_j + 2] = sum_b;
                }
            }
        }
    }
    // ピクセルデータ反映
    context.putImageData(pxdata, 0, 0);
}

/*
 * セピア色に変換
 */
function sepia(canvas_name) 
{
	// canvas取得
	var canvas = document.getElementById(canvas_name);
	// canvasのコンテキスト取得
	var context = canvas.getContext("2d");
    // ピクセルデータ取得
    var pxdata = context.getImageData(0, 0, canvas.width, canvas.height);

	for (var i = 0; i < pxdata.width * pxdata.height; i++) {
		// 参考にした式（Yが明るさ）
		// Y = 0.30R +	0.59G + 0.11B
		// I = 0.60R -	0.28G - 0.32B
		// Q = 0.21R -	0.52G + 0.31B
		// 以下がセピア
		// R = (Y/255) * 240
		// G = (Y/255) * 200
		// B = (Y/255) * 145
		var y = (pxdata.data[i * 4] * 0.30) + (pxdata.data[i * 4 + 1] * 0.59) + (pxdata.data[i * 4 + 2] * 0.11);
		pxdata.data[i * 4] = (y / 255) * 240;
		pxdata.data[i * 4 + 1] = (y / 255) * 200;
		pxdata.data[i * 4 + 2] = (y / 255) * 145;
	}

	// ピクセルデータ反映
	context.putImageData(pxdata, 0, 0);
}

/*
 * モノクロに変換
 */
function mono(canvas_name)
{
	// canvas取得
	var canvas = document.getElementById(canvas_name);
	// canvasのコンテキスト取得
	var context = canvas.getContext("2d");
    // ピクセルデータ取得
    var pxdata = context.getImageData(0, 0, canvas.width, canvas.height);

	for (var i = 0; i < pxdata.width * pxdata.height; i++) {
		// 参考にした式（Yが明るさ）
		// Y = 0.30R +	0.59G + 0.11B
		// I = 0.60R -	0.28G - 0.32B
		// Q = 0.21R -	0.52G + 0.31B
		var y = (pxdata.data[i * 4] * 0.30) + (pxdata.data[i * 4 + 1] * 0.59) + (pxdata.data[i * 4 + 2] * 0.11);
		pxdata.data[i * 4] = y;
		pxdata.data[i * 4 + 1] = y;
		pxdata.data[i * 4 + 2] = y;
	}

	// ピクセルデータ反映
	context.putImageData(pxdata, 0, 0);
}
